﻿using AhpilyServer;
using AhpilyServer.Concurrent;
using System.Collections.Generic;

namespace PokerServer.Cache.Match
{
    /// <summary>
    /// 匹配的缓存层
    /// </summary>
    public class MatchCache
    {
        /// <summary>
        /// 代表 正在等待的 用户id 和房间id 的映射
        /// </summary>
        private readonly Dictionary<int, int> uidRoomIdDict = new Dictionary<int, int>();

        /// <summary>
        /// 代表 正在等待的房间 和 房间的数据模型 的映射
        /// </summary>
        private readonly Dictionary<int, MatchRoom> idModelDict = new Dictionary<int, MatchRoom>();


        /// <summary>
        /// 代表 重用的房间 队列
        /// </summary>
        readonly Queue<MatchRoom> roomQueue = new Queue<MatchRoom>();

        /// <summary>
        /// 代表 房间的id
        /// </summary>
        private readonly ConcurrentInt Id = new ConcurrentInt(-1);

        /// <summary>
        /// 进入匹配队列 进入匹配房间
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public MatchRoom Enter(int userId, ClientPeer client)
        {
            // 遍历等待的房间 看一下 有没有正在等待的 
            // 有 就加入访问的玩家
            foreach (MatchRoom mr in idModelDict.Values)
            {
                if (mr.IsFull())
                {
                    continue;
                }

                // 该房间没满
                mr.Enter(userId, client);

                uidRoomIdDict.Add(userId, mr.Id);
                return mr;
            }

            MatchRoom room;
            // 自己开房
            if (roomQueue.Count > 0)
            {
                room = roomQueue.Dequeue();
            }
            else
            {
                room = new MatchRoom(Id.Add_Get());
            }

            room.Enter(userId, client);

            idModelDict.Add(room.Id, room);
            uidRoomIdDict.Add(userId, room.Id);
            return room;
        }


        /// <summary>
        /// 离开匹配房间
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public MatchRoom Leave(int userId)
        {
            int roomId = uidRoomIdDict[userId];
            MatchRoom room = idModelDict[roomId];
            room.Leave(userId);

            // 还要处理
            uidRoomIdDict.Remove(userId);
            if (room.IsEmpty())
            {
                // 回收空房间
                idModelDict.Remove(roomId);
                roomQueue.Enqueue(room);
            }

            return room;
        }

        /// <summary>
        /// 用户是否正在匹配
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public bool IsMatching(int userId)
        {
            return uidRoomIdDict.ContainsKey(userId);
        }

        /// <summary>
        /// 获取玩家所在的等待房间
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public MatchRoom GetRoom(int userId)
        {
            int roomId = uidRoomIdDict[userId];
            MatchRoom room = idModelDict[roomId];
            return room;
        }

        /// <summary>
        /// 摧毁房间的数据然后重用
        /// </summary>
        /// <param name="room"></param>
        public void Destroy(MatchRoom room)
        {
            idModelDict.Remove(room.Id);
            foreach (var userId in room.UIdClientDict.Keys)
            {
                uidRoomIdDict.Remove(userId);
            }

            // 清空数据
            room.UIdClientDict.Clear();
            room.readyUIdList.Clear();

            roomQueue.Enqueue(room);
        }
    }
}